home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Language / Compiler / construct.c < prev    next >
C/C++ Source or Header  |  1990-08-16  |  8KB  |  312 lines

  1. /*
  2.  * @(#)construct.c    1.5  1/20/89
  3.  */
  4. #include "assert.h"
  5. #include "nodes.h"
  6. #include "keyword.h"
  7. #include "system.h"
  8. #include "sequence.h"
  9. #include "semantics.h"
  10.  
  11. NodePtr RCONS(list, anElement)
  12. NodePtr list, anElement;
  13. {
  14.   register NodePtr newlist;
  15.   register int length;
  16.   if (list == NULL) {
  17.     newlist = F_NewNode(T_SEQUENCE, 4);
  18.   } else if (list->nChildren >= list->maxChildren) {
  19.     length = list->maxChildren;
  20.     newlist = F_NewNode(list->tag, 2 * length);
  21.     bcopy((char *)list, (char *)newlist, NodeSize(list));
  22.     newlist->maxChildren = 2 * length;
  23.     free((char *)list);
  24.     } else {
  25.       newlist = list;
  26.     }
  27.   if (newlist->nChildren == 0 && (int) anElement > 0x200)
  28.     newlist->lineNumber = anElement->lineNumber;
  29.   newlist->b.children[newlist->nChildren] = anElement;
  30.   newlist->nChildren++;
  31.   return(newlist);
  32. }
  33.  
  34. NodePtr RAPPEND(list, listOrElement)
  35. NodePtr list, listOrElement;
  36. {
  37.   register NodePtr q;
  38.   if (! isASequence(list)) {
  39.     q = F_NewNode(T_SEQUENCE, 4);
  40.     q->nChildren = 1;
  41.     q->b.children[0] = list;
  42.     list = q;
  43.   }
  44.   if (listOrElement == NULL) 
  45.     return(list);
  46.   if ((int)listOrElement <= 0x200 || listOrElement->tag != T_SEQUENCE)
  47.     return(RCONS(list, listOrElement));
  48.   Sequence_For(q, listOrElement)
  49.     list = RCONS(list, q);
  50.   Sequence_Next
  51.   free((char *)listOrElement);
  52.   return(list);
  53. }
  54.  
  55. /*VARARGS2*/
  56. NodePtr Construct(t, nargs, therest)
  57. Tag t;
  58. int nargs;
  59. NodePtr therest;
  60. {
  61.   register NodePtr *args = &therest;
  62.   register NodePtr p;
  63.   register int i;
  64.   int minLineNumber;
  65.   
  66.   p = F_NewNode(t, nargs);
  67.   minLineNumber = p->lineNumber;
  68.   for (i = 0; i < nargs; i++) {
  69.     p->b.children[p->firstChild+i] = args[i];
  70.     if ((int) args[i] > 0x200 && args[i]->lineNumber < minLineNumber) 
  71.       minLineNumber = args[i]->lineNumber;
  72.   }
  73.   p->nChildren += nargs;
  74.   p->lineNumber = minLineNumber;
  75.   return (p);
  76. }
  77.  
  78. NodePtr makeOpName(p)
  79. NodePtr p;
  80. {
  81.   register NodePtr result;
  82.   if ((int) p <= 0x200) {
  83.     result = Construct(P_OPNAME, 0);
  84.     result->b.opname.ident = (int)p - firstKeyword;
  85.     return(result);
  86.   } else if (p->tag == T_IDENT) {
  87.     result = Construct(P_OPNAME, 0);
  88.     result->b.opname.ident = p->b.ident.ident;
  89.     free((char *)p);
  90.     return(result);
  91.   } else {
  92.     assert (p->tag == P_OPNAME);
  93.     return(p);
  94.   }
  95. }
  96.  
  97. /*
  98. * fD1 is a primary, fD2 is a sequence of selections.  Each selection is:
  99. *   P_SELECTION NULL opname argumentlist
  100. *   P_FIELDSEL NULL identifier
  101. *   P_SUBSCRIPT NULL expression
  102. * We want to build the unsugared node, either:
  103. *   P_INVOC rest opname argumentlist
  104. *   P_FIELDSEL rest identifier
  105. *   P_SUBSCRIPT rest expression
  106. */
  107. NodePtr buildSelection(fD1, fD2)
  108. NodePtr fD1, fD2;
  109. {
  110.   Tag tag;
  111.   register NodePtr result, thisOne, q;
  112.  
  113.   result = fD1;
  114.   Sequence_For(thisOne, fD2)
  115.     tag = thisOne->tag;
  116.     switch (tag) {
  117.       case P_SELECTION:
  118.     q = Construct(P_INVOC, 3, result,
  119.       thisOne->b.selection.opname, thisOne->b.selection.args);
  120.     q->lineNumber = thisOne->lineNumber;
  121.     free((char *) thisOne);
  122.     thisOne = q;
  123.     break;
  124.       case P_FIELDSEL:
  125.     thisOne->b.fieldsel.target = result;
  126.     break;
  127.       case P_SUBSCRIPT:
  128.     thisOne->b.subscript.target = result;
  129.     break;
  130.       default:
  131.     assert(FALSE);
  132.     break;
  133.     }
  134.     result = thisOne;
  135.   Sequence_Next
  136.   Free(fD2);
  137.   return(result);
  138. }
  139.  
  140. /*
  141. * fD1 is a list of operators, fD2 is an expression.  We want to build
  142. *   P_INVOC rest opname null
  143. */
  144. NodePtr buildExpression1(fD1, fD2)
  145. NodePtr fD1, fD2;
  146. {
  147.   NodePtr result, operator;
  148.   if (fD1 == NULL) return (fD2);
  149.   result = fD2;
  150.   Sequence_ReverseFor(operator, fD1)
  151.     if ((int) operator == KLOCATE || (int) operator == KISFIXED ||
  152.       (int) operator == KAWAITING) {
  153.       result = Construct(P_UNARYEXP, 2, operator, result);
  154.     } else {
  155.       result = Construct(P_INVOC, 3, result, makeOpName(operator), NULL);
  156.     }
  157.   Sequence_Next
  158.   Free(fD1);
  159.   return(result);
  160. }
  161.  
  162. /*
  163. * Here there are a couple of cases.  If the operation name is one of the
  164. * funny control flow ones KAND, KOR, OIDENTITY, ONOTIDENTITY, OCONFORMSTO
  165. * then we want to build a special node.  Otherwise we treat it like in
  166. * buildExpression1.
  167. * Here fD1 is a sequence of expressions separated by operators.
  168. */
  169. NodePtr buildExpression2(fD1)
  170. NodePtr fD1;
  171. {
  172.   register int i, maxIndex;
  173.   register NodePtr result, operation, argument;
  174.   Tag tag;
  175.   
  176.   assert(fD1->firstChild == 0);
  177.   result = fD1->b.children[0];
  178.   maxIndex = fD1->nChildren - 1;
  179.   for (i = 1; i <= maxIndex ; i += 2) {
  180.     operation = fD1->b.children[i];
  181.     argument = fD1->b.children[i + 1];
  182.     if ((int) operation == KAND        || (int) operation == KOR ||
  183.       (int) operation == OIDENTITY || (int) operation == ONOTIDENTITY ||
  184.       (int) operation == OCONFORMSTO) {
  185.       tag = P_EXP;
  186.     } else {
  187.       tag = P_INVOC;
  188.       operation = makeOpName(operation);
  189.       argument = Construct(T_SEQUENCE, 1, Construct(P_ARG, 1, argument));
  190.     }
  191.     result = Construct(tag, 3, result, operation, argument);
  192.   }
  193.   Free(fD1);
  194.   return(result);
  195. }
  196.  
  197. NodePtr Flatten(fSeq)
  198. NodePtr fSeq;
  199. {
  200.   register NodePtr q, r, result;
  201.   register int count = 0;
  202.   assert(fSeq->tag == T_SEQUENCE);
  203.   Sequence_For(q, fSeq)
  204.     if (q->tag == T_SEQUENCE) {
  205.       count += q->nChildren;
  206.     } else {
  207.       count ++;
  208.     }
  209.   Sequence_Next
  210.   if (count == fSeq->nChildren) return(fSeq);
  211.  
  212.   result = F_NewNode(T_SEQUENCE, count);
  213.   result->nChildren = count;
  214.   count = 0;
  215.   Sequence_For(q, fSeq)
  216.     if ((int)q >= 0x200 && q->tag == T_SEQUENCE) {
  217.       Sequence_For(r, q)
  218.     result->b.children[count++] = r;
  219.       Sequence_Next
  220.       free((char *)q);
  221.     } else {
  222.       result->b.children[count++] = q;
  223.     }
  224.   Sequence_Next
  225.   assert(count == result->nChildren);
  226.   free((char *)fSeq);
  227.   return(result);
  228. }
  229.  
  230. NodePtr Distribute(fTag, fSeq, nArgs, firstArg)
  231. Tag fTag;
  232. NodePtr fSeq, firstArg;
  233. int nArgs;
  234. {
  235.   register int i, j;
  236.   register NodePtr *args = &firstArg;
  237.  
  238.   register NodePtr result, thisOne;
  239.   assert(fSeq->tag == T_SEQUENCE);
  240.   if (fSeq->nChildren == 1) {
  241.     result = F_NewNode(fTag, nArgs+1);
  242.     result->nChildren += nArgs+1;
  243.     result->b.children[result->firstChild] = fSeq->b.children[0];
  244.     result->lineNumber = fSeq->b.children[0]->lineNumber;
  245.     for (j = 0; j < nArgs; j++)
  246.       result->b.children[result->firstChild+j+1] = args[j];
  247.     free((char *)fSeq);
  248.   } else {
  249.     result = F_NewNode(T_SEQUENCE, fSeq->nChildren);
  250.     result->nChildren = fSeq->nChildren;
  251.     for (i = 0; i < fSeq->nChildren; i++) {
  252.       thisOne = F_NewNode(fTag, nArgs + 1);
  253.       result->b.children[i] = thisOne;
  254.       thisOne->nChildren += nArgs + 1;
  255.       thisOne->b.children[thisOne->firstChild] = fSeq->b.children[i];
  256.       thisOne->lineNumber = fSeq->b.children[i]->lineNumber;
  257.       for (j = 0; j < nArgs; j++)
  258.     thisOne->b.children[thisOne->firstChild+j+1] = args[j];
  259.     }
  260.     result->lineNumber = result->b.children[0]->lineNumber;
  261.     free((char *)fSeq);
  262.   }
  263.   return(result);
  264. }
  265.  
  266. NodePtr Copy(fNode)
  267. register NodePtr fNode;
  268. {
  269.   register NodePtr result;
  270.   register int i;
  271.   if ((int) fNode <= 0x200) return(fNode);
  272.   else {
  273.     result = F_NewNode(fNode->tag, fNode->nChildren-fNode->firstChild);
  274.     result->nChildren = fNode->nChildren;
  275.     for (i = 0; i < fNode->firstChild; i++) {
  276.       result->b.children[i] = fNode->b.children[i];
  277.     }
  278.     for (i = fNode->firstChild; i < fNode->nChildren; i++) {
  279.       result->b.children[i] = Copy(fNode->b.children[i]);
  280.     }
  281.     return(result);
  282.   }
  283. }
  284.  
  285. NodePtr Copy1Node(fNode)
  286. register NodePtr fNode;
  287. {
  288.   register NodePtr result;
  289.   if ((int) fNode <= 0x200) return(fNode);
  290.   else {
  291.     result = F_NewNode(fNode->tag, fNode->nChildren-fNode->firstChild);
  292.     bcopy((char *)fNode, (char *)result, NodeSize(fNode));
  293.     return(result);
  294.   }
  295. }
  296.  
  297. NodePtr singleArg(n)
  298. NodePtr n;
  299. {
  300.   return(Construct(T_SEQUENCE, 1, (Construct(P_ARG, 1, n))));
  301. }
  302.  
  303. NodePtr buildString(s)
  304. char *s;
  305. {
  306.   NodePtr r;
  307.   r = Construct(P_STRINGLIT, 0);
  308.   r->b.stringlit.string = malloc(strlen(s) + 1);
  309.   strcpy(r->b.stringlit.string, s);
  310.   return(r);
  311. }
  312.